home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1992 June: ROMin Holiday / ADC Developer CD (1992-06) (''ROMin Holiday'')_iso / Developer Connection - 06-1992.iso / Periodicals / develop / develop 7 code / QuickTime / SimpleInMovies / SimpleInController.c next >
Encoding:
C/C++ Source or Header  |  1992-01-13  |  15.4 KB  |  456 lines  |  [TEXT/MPS ]

  1. /*     
  2. SimpleInMovies
  3.  
  4. Sample programs demonstrating how to open and display
  5. QuickTime™ Movies.
  6.  
  7. SimpleInController.c file contains the code for the routines 
  8. having to do with the standard movie controller.
  9.  
  10. Each window is associated with a movie and an instance of the movie
  11. controller. There are menu equivalents for movie controller commands
  12. to show how to interact with the controller.
  13.  
  14. Guillermo A. Ortiz
  15. Macintosh Developer Technical Support
  16.  
  17. 07/23/91 Moved the code here and added editing stuff
  18. 08/07/91 Added code to put cuts into the scrap when being switched in/out.
  19. 08/22/91 Changed FixMovieWindow to accomodate changes in standard controler box.
  20. 11/17/91 Fix final interface problems, clean comments.
  21.  
  22. FROM Beta README:
  23.  
  24. GONE:  The following mcActions have been removed:
  25.         mcStop, mcPlayBackwards, mcSetRate, mcIncreaseRate, mcDecreaseRate
  26.             use mcPlay instead
  27.         
  28.         mcStepForward, mcStepBackward 
  29.             use mcStep instead
  30.         
  31.         mcToggleLooping
  32.             use mcGetLooping and mcSetLooping
  33.         
  34.         mcIncreaseVolume, mcDecreaseVolume
  35.             use mcGetVolume and mcSetVolume
  36.         
  37.         mcSetSelectionBegin, mcSetSelectionEnd
  38.             changed to mcSetSelectionBegin and mcSetSelectionDuration, with the behaviour that mcSetSelectionBegin does nothing, just saves the time passed, and mcSetSelectionDuration then applies the beginning and the duration to the movie. Also, the duration can be negative.
  39.  
  40. */
  41.  
  42. #include <SimpleInMovie.h>
  43.  
  44. Movie cuts;                    /* local scrappy movie */
  45.  
  46. void ChangeMooVState(void);
  47. void ChangeMooVSound(void);
  48. void NextMooVFrame(void);
  49. void PrevMooVFrame(void);
  50. void SetMovieLoop(short);
  51. void DoEnableEditing(void);
  52.  
  53. void DoUndoMovie(void);
  54. void DoCutMovie(void);
  55. void DoCopyMovie(void);
  56. void DoPasteMovie(void);
  57. void DoClearMovie(void);
  58. void DoSelectAll(void);
  59.  
  60. extern void DoScrapStuff(Boolean toScrap);
  61.  
  62. OSErr FixMovieWindow(WindowPtr window);
  63.  
  64. Boolean IsPlayerEvent(WindowPtr, EventRecord *);
  65. extern Boolean IsAppWindow(WindowPtr);
  66.  
  67. /*******************************************************************************************
  68.  *******************************************************************************************/
  69. /* the following rutines service menu commands that have to do with the movie being
  70.    played; we call the controller to affect the action because this allows the controller
  71.    to be in sync with the movie.
  72.    
  73.    If you change the state of the movie through Movie Toolbox routines you have to call
  74.    MCMovieChanged in order to allow the controller to get back in sync.
  75. */
  76.  
  77. /* stops or starts the movie */
  78. void ChangeMooVState()
  79. {
  80. WindowPtr window;
  81. DocRecHandle wHndl;
  82.  
  83.   if (window = FrontWindow()) { /* don't bother if no movies to play */
  84.     if (IsAppWindow(window) && (wHndl = (DocRecHandle)GetWRefCon(window)) ) {
  85.       if ( GetMovieRate((*wHndl)->wMovie) ) {/* the movie is playing call controller to stop it */
  86.         MCDoAction((*wHndl)->wPlayer, mcActionPlay, 0x0000000); /* rate=zero to stop */
  87.       }
  88.       else  { /* needs to start movie */
  89.         MCDoAction((*wHndl)->wPlayer, mcActionPlay, (Ptr)0x00010000); /* rate=one to play */
  90.       }
  91.     }
  92.   }
  93. }
  94.  
  95. /* sets sound on or off */
  96. void ChangeMooVSound()
  97. {
  98. WindowPtr window;
  99. DocRecHandle wHndl;
  100. short vol;
  101.  
  102.   if (window = FrontWindow()) { /* don't bother if no movies to play */
  103.     if (IsAppWindow(window) && (wHndl = (DocRecHandle)GetWRefCon(window)) ) {
  104.       MCDoAction((*wHndl)->wPlayer , mcActionGetVolume, &vol);     /* get current volume     */
  105.       if (vol) {
  106.         (*wHndl)->soundVolume = vol;
  107.         vol = 0;
  108.         MCDoAction((*wHndl)->wPlayer , mcActionSetVolume, (Ptr)vol);     /* and set it        */
  109.       }
  110.       else {
  111.         vol = (*wHndl)->soundVolume;
  112.         MCDoAction((*wHndl)->wPlayer , mcActionSetVolume, (Ptr)vol);     /* and set it        */
  113.       }
  114.     }
  115.   }
  116. }
  117.  
  118. /* advances one frame */
  119. void NextMooVFrame()
  120. {
  121. short step = 1;                /* advance one frame        */
  122. WindowPtr window;
  123. DocRecHandle wHndl;
  124. ComponentResult err;
  125.  
  126.   if (window = FrontWindow()) { /* don't bother if no movies to play */
  127.     if (IsAppWindow(window) && (wHndl = (DocRecHandle)GetWRefCon(window)) ) {
  128.       if ( err = MCDoAction((*wHndl)->wPlayer, mcActionStep, (Ptr)step) )
  129.         DebugStr("\pError at step forward");
  130.     }
  131.   }
  132.   
  133. }
  134.  
  135. /* goes to previous frame */
  136. void PrevMooVFrame()
  137. short step = -1;            /* Negative values go backwards    */
  138. WindowPtr window;
  139. DocRecHandle wHndl;
  140. ComponentResult err;
  141.  
  142.   if (window = FrontWindow()) { /* don't bother if no movies to play */
  143.     if (IsAppWindow(window) && (wHndl = (DocRecHandle)GetWRefCon(window)) ) {
  144.       if ( err = MCDoAction((*wHndl)->wPlayer, mcActionStep, (Ptr)step) )
  145.         DebugStr("\pError at step backward");
  146.     }
  147.   }  
  148. }
  149.  
  150. /* Handle changes to loop settings and also turns palindrome on or off */
  151. void SetMovieLoop(whatAction)
  152. short whatAction;
  153. {
  154. WindowPtr window;
  155. DocRecHandle wHndl;
  156. Boolean isLooping;
  157.  
  158.     if (window = FrontWindow()) { /* don't bother if no movies to play */
  159.       if (IsAppWindow(window) && (wHndl = (DocRecHandle)GetWRefCon(window)) ) {
  160.         switch (whatAction) {
  161.             case loopMovie:
  162.               MCDoAction((*wHndl)->wPlayer, mcActionGetLooping, (void *)&isLooping);
  163.               MCDoAction((*wHndl)->wPlayer, mcActionSetLooping, (void *)!isLooping);
  164.               break;
  165.             case weirdLoopMovie:
  166.               MCDoAction((*wHndl)->wPlayer, mcActionGetLoopIsPalindrome, (void *)&isLooping);
  167.               MCDoAction((*wHndl)->wPlayer, mcActionSetLoopIsPalindrome, (void *)!isLooping);
  168.               break;
  169.         }
  170.       }
  171.     }
  172. }
  173.  
  174. /*******************************************************************************************
  175.  *******************************************************************************************/
  176. /* the idea in this function is to check if the event being handled
  177.    belongs to one instance of the controller; even when it is not a controller event we want
  178.    to call the component to let it handle idle events. If the controller decides
  179.    that it has one event it needs to handle and returns true the function returns
  180.    true; in other cases the function returns false and lets the normal event loop to fall through
  181. */
  182.  
  183. Boolean IsPlayerEvent(window, myEvent)
  184. WindowPtr window;
  185. EventRecord *myEvent;
  186. {
  187. #pragma unused (window)
  188.  
  189. DocRecHandle    wHndl;
  190. WindowPtr        wind;
  191. Boolean            result = false;
  192.     /* loop for each window until event has been taken care of or there are no more windows */
  193.     for (wind = *(WindowPtr *)WindowList;wind;wind = (WindowPtr)((WindowPeek)wind)->nextWindow) {     /* there may not be a window */
  194.       if (wHndl = (DocRecHandle)GetWRefCon(wind)) {     /* Get the storage handle */
  195.         result |= (MCIsPlayerEvent((*wHndl)->wPlayer, myEvent)); /* return true if controller event is handled */
  196.       }
  197.     }
  198.     return result;
  199. }
  200.  
  201. /*******************************************************************************************
  202.  *******************************************************************************************/
  203. /* Routines to handle editing commands */
  204.  
  205. /* Functions toggles editing on/off */
  206. void DoEnableEditing(void)
  207. {
  208. WindowPtr window;
  209. DocRecHandle wHndl;
  210.  
  211.     if (window = FrontWindow()) { /* don't bother if no movies to play */
  212.       if (IsAppWindow(window) && (wHndl = (DocRecHandle)GetWRefCon(window)) ) {
  213.         MCEnableEditing((*wHndl)->wPlayer,!MCIsEditingEnabled((*wHndl)->wPlayer));
  214.       }
  215.     }
  216. }
  217.  
  218. /* Undos edits */
  219. void DoUndoMovie(void)
  220. {
  221. WindowPtr window;
  222. DocRecHandle wHndl;
  223. ComponentResult err;
  224.  
  225.     if (window = FrontWindow()) { /* don't bother if no movies to play */
  226.       if (IsAppWindow(window) && (wHndl = (DocRecHandle)GetWRefCon(window)) ) {
  227.         if ( MCIsEditingEnabled((*wHndl)->wPlayer)) {
  228.           if ( ! MCIsControllerAttached((*wHndl)->wPlayer) )      /* if needed, atach it before    */
  229.              MCSetControllerAttached((*wHndl)->wPlayer, true);     /* performing operation            */
  230.  
  231. /* depending on what is being undo, this operation could leave an empty box movie, since
  232.    the controller is still attached it would jump to the top of the window; later on
  233.    the update that follows the controller goes away but it looks kind of ugly so we
  234.    make it invisible here, after repositioning the controller FixMovieWindow will
  235.    turn it on again.
  236. */
  237.           MCSetVisible((*wHndl)->wPlayer, false);
  238.           if ( err = MCUndo((*wHndl)->wPlayer) )
  239.             DebugStr("\pError at MCUndo");
  240.           else
  241.             if (FixMovieWindow(window))  /* movie size may have changed, check it up */
  242.               DebugStr("\pSomething wrong at FixMovieWindow");
  243.         }
  244.       }
  245.     }
  246. }
  247.  
  248. void DoCutMovie(void)
  249. {
  250. WindowPtr window;
  251. DocRecHandle wHndl;
  252.  
  253.     if (window = FrontWindow()) { /* don't bother if no movies to play */
  254.       if (IsAppWindow(window) && (wHndl = (DocRecHandle)GetWRefCon(window)) ) {
  255.         if ( MCIsEditingEnabled((*wHndl)->wPlayer)) {
  256.           if ( ! MCIsControllerAttached((*wHndl)->wPlayer) )      /* if needed, atach it before    */
  257.              MCSetControllerAttached((*wHndl)->wPlayer, true);     /* performing operation            */
  258.           if (cuts)
  259.             DisposeMovie(cuts);            /* get rid of movie    first */
  260.  
  261. /* Cut can result in an empty box movie; therefore make controller invisible and then let
  262.    FixMovieWindow turn it on when all the repositioning is done.
  263. */
  264.           MCSetVisible((*wHndl)->wPlayer, false);
  265.           if ( !(cuts = MCCut((*wHndl)->wPlayer)) ) {
  266.             DebugStr("\pError at MCCut");
  267.           }
  268.           if (FixMovieWindow(window)) /* movie size may have changed, check it up */
  269.             DebugStr("\pSomething wrong at FixMovieWindow");
  270.         }
  271.       }
  272.     }
  273. }
  274.  
  275. void DoCopyMovie(void)
  276. {
  277. WindowPtr window;
  278. DocRecHandle wHndl;
  279.  
  280.     if (window = FrontWindow()) { /* don't bother if no movies to play */
  281.       if (IsAppWindow(window) && (wHndl = (DocRecHandle)GetWRefCon(window)) ) {
  282.         if ( MCIsEditingEnabled((*wHndl)->wPlayer)) {
  283.           if (cuts)
  284.             DisposeMovie(cuts);            /* get rid of movie    first */
  285.           if ( !(cuts = MCCopy((*wHndl)->wPlayer)) ) {
  286.             DebugStr("\pError at MCCopy"); /* nothing selected maybe*/
  287.           }
  288.         }
  289.       }
  290.     }
  291. }
  292.  
  293. /* Pastes movie pieces into front most window if editing is enabled.
  294.    But first it check if the movie has its controller attached, if not (the
  295.    movie has no spatial bounds, empty or no video movie, then the controller is attached.
  296.    The call to FisMovieWindow would detach the controller if the movie still has no
  297.    bounds.
  298. */
  299. void DoPasteMovie(void)
  300. {
  301. WindowPtr window;
  302. DocRecHandle wHndl;
  303. ComponentResult err;
  304.  
  305.     if (window = FrontWindow()) { /* don't bother if no movies to play */
  306.       if (cuts && IsAppWindow(window) && (wHndl = (DocRecHandle)GetWRefCon(window)) ) {
  307.         if ( MCIsEditingEnabled((*wHndl)->wPlayer)) {
  308.           if ( ! MCIsControllerAttached((*wHndl)->wPlayer) )  /* if needed            */
  309.              MCSetControllerAttached((*wHndl)->wPlayer, true); /* atach it             */
  310.  
  311. /* paste can result in an empty box movie; therefore make controller invisible and then let
  312.    FixMovieWindow turn it on when all the repositioning is done.
  313. */
  314.           MCSetVisible((*wHndl)->wPlayer, false);
  315.           if ( err = MCPaste((*wHndl)->wPlayer, cuts) ) {
  316.             DebugStr("\pError at MCPaste");
  317.           }
  318.           else
  319.             if (FixMovieWindow(window)) 
  320.               DebugStr("\pSomething wrong at FixMovieWindow");
  321.         }
  322.       }
  323.     }
  324. }
  325.  
  326. void DoClearMovie(void)
  327. {
  328. WindowPtr window;
  329. DocRecHandle wHndl;
  330. ComponentResult err;
  331.  
  332.     if (window = FrontWindow()) { /* don't bother if no movies to play */
  333.       if (IsAppWindow(window) && (wHndl = (DocRecHandle)GetWRefCon(window)) ) {
  334.         if ( MCIsEditingEnabled((*wHndl)->wPlayer)) {
  335.  
  336.           if ( ! MCIsControllerAttached((*wHndl)->wPlayer) )  /* if needed            */
  337.              MCSetControllerAttached((*wHndl)->wPlayer, true); /* atach it             */
  338.  
  339. /* Clear can result in an empty box movie; therefore make controller invisible and then let
  340.    FixMovieWindow turn it on when all the repositioning is done.
  341. */
  342.           MCSetVisible((*wHndl)->wPlayer, false);
  343.  
  344.           if ( err = MCClear((*wHndl)->wPlayer) ) {
  345.             DebugStr("\pError at MCClear");
  346.           }
  347.           if (FixMovieWindow(window)) /* movie size may have changed, check it up */
  348.             DebugStr("\pSomething wrong at FixMovieWindow");
  349.         }
  350.       }
  351.     }
  352. }
  353.  
  354. /* selects the whole movie for editing */
  355. void DoSelectAll(void)
  356. {
  357. WindowPtr window;
  358. DocRecHandle wHndl;
  359. ComponentResult err;
  360. TimeRecord tRec;
  361.  
  362.     if (window = FrontWindow()) { /* don't bother if no movies to play */
  363.       if (IsAppWindow(window) && (wHndl = (DocRecHandle)GetWRefCon(window)) ) {
  364.         if ( MCIsEditingEnabled((*wHndl)->wPlayer)) {
  365.           tRec.value.lo = tRec.value.hi = 0;
  366.           tRec.base = 0;
  367.           tRec.scale = GetMovieTimeScale((*wHndl)->wMovie);
  368.           if ( err = MCDoAction((*wHndl)->wPlayer, mcActionSetSelectionBegin, &tRec)) {
  369.               DebugStr("\pError trying mcActionSetSelectionBegin");
  370.           }
  371.           
  372.           tRec.value.hi = 0;
  373.           tRec.value.lo = GetMovieDuration((*wHndl)->wMovie);
  374.           tRec.base = 0;
  375.           tRec.scale = GetMovieTimeScale((*wHndl)->wMovie);
  376.           if ( err = MCDoAction((*wHndl)->wPlayer, mcActionSetSelectionDuration, &tRec)) {
  377.               DebugStr("\pError trying mcActionSetSelectionDuration");
  378.           }
  379.         }
  380.       }
  381.     }
  382. }
  383.  
  384.  
  385. /*******************************************************************************************
  386.  *******************************************************************************************/
  387. /* Utility proc that fixes the size of the display window when the dimensions have changed;
  388.    it expects all the checks done when called.
  389. */
  390. OSErr FixMovieWindow(WindowPtr window)
  391. WindowPtr window;
  392. {
  393. DocRecHandle wHndl;
  394. Rect moovBox, controllerBox;
  395. OSErr err = noErr;
  396.  
  397.     if (wHndl = (DocRecHandle)GetWRefCon(window)) {
  398.       GetMovieBox((*wHndl)->wMovie,&moovBox); /* Use the movie box to resize window */
  399.       if ( ! EmptyRect(&moovBox)) {
  400.       /* usual case when movie has video to show */
  401.         if (err = MCGetControllerBoundsRect((*wHndl)->wPlayer, &controllerBox) )
  402.           DebugStr("\pError at MCGetControllerBoundsRect");
  403.  
  404.         UnionRect(&moovBox, &controllerBox, &moovBox);
  405.  
  406.         SizeWindow(window, moovBox.right-moovBox.left,moovBox.bottom-moovBox.top,true);
  407.       }
  408.       else { /* new movie or a movie that lost all visible portions through editing */
  409.       /* positioning the controller while it is attached is not possible so we detach it
  410.          in order to avoid the controller jumping to the top of the window when the
  411.          movie has not visible stuff.
  412.       */
  413.         if ( MCIsControllerAttached((*wHndl)->wPlayer) )
  414.           MCSetControllerAttached((*wHndl)->wPlayer, false); /* detach it */
  415.         if (err = MCGetControllerBoundsRect((*wHndl)->wPlayer, &controllerBox) )
  416.           DebugStr("\pError at MCGetControllerBoundsRect");
  417.         controllerBox.top =   ((GrafPtr) window)->portRect.bottom - controllerBox.bottom;
  418.         controllerBox.right = ((GrafPtr) window)->portRect.right;
  419.         controllerBox.bottom = ((GrafPtr) window)->portRect.bottom;
  420.         MCPositionController((*wHndl)->wPlayer, &moovBox, &controllerBox, mcTopLeftMovie /*controllerCreationFlags*/);
  421.       }
  422.  
  423.     }
  424.     if ( ! MCGetVisible((*wHndl)->wPlayer) ) {
  425.       if ( err = MCSetVisible((*wHndl)->wPlayer, true) )
  426.           DebugStr("\pError at MCSetVisible");
  427.     }
  428.     return err;
  429. }
  430.  
  431. /*******************************************************************************************
  432.  *******************************************************************************************/
  433. /* This procedure gets called with suspend and resume events to
  434.    put a movie into the scrap when being switched back and to get the scrap
  435.    when comming to the front.
  436. */
  437. extern void DoScrapStuff(toScrap)
  438. Boolean toScrap;
  439. {
  440. OSErr err;
  441.     if (toScrap)     /* check if we have a movie to     */
  442.       if (cuts)     /* put in the scrap                */
  443.         if ( err = PutMovieOnScrap(cuts, 0L) ) /* now put it there */
  444.           DebugStr("\pSomething wrong trying to put movie to scrap");
  445.     else { 
  446.     /* convert scrap to local */
  447.       if (cuts)    
  448.         DisposeMovie(cuts);            /* get rid of movie    first */
  449.       if ( !(cuts = NewMovieFromScrap(0) ) )
  450.         DebugStr("\pSomething wrong trying to get movie from scrap");
  451.     }
  452. }
  453. /*******************************************************************************************
  454.  *******************************************************************************************/
  455.